package util

import (
	"encoding/json"
	"fmt"
	"github.com/go-redis/redis"
	"go.uber.org/zap"
	"ops.alert.center.service/internal/middleware"
	"ops.alert.center.service/internal/model"
	"reflect"
	"strconv"
	"strings"
	"time"
)

var Cluster *redis.Client

func InitRedis() (err error) {
	Cluster = redis.NewFailoverClient(&redis.FailoverOptions{
		MasterName:         middleware.RedisMaster,
		SentinelAddrs:      middleware.Redis,
		Password:           middleware.RedisPwd,
		DB:                 0,
		MaxRetries:         1,
		DialTimeout:        time.Second * 2,
		ReadTimeout:        time.Second * 5,
		WriteTimeout:       time.Second * 5,
		PoolSize:           32,
		IdleTimeout:        time.Minute * 2,
		IdleCheckFrequency: time.Second * 30,
	})
	_, err = Cluster.Ping().Result()
	if err != nil {
		fmt.Println("redis连接失败!!", err)
		middleware.Logger.Info("initRedis eror",
			zap.Error(err),
		)
		return err
	}
	fmt.Println("redis连接成功!!")
	return nil
}

//塞入redis
func InsertRedis(thisEvent model.AlertEvent) {
	thisEventMarshal, _ := json.Marshal(thisEvent)
	thisTime := strconv.FormatInt((time.Now().Unix()), 10)
	err := Cluster.Set(middleware.RedisMasterKey+thisTime, thisEventMarshal, time.Second*100).Err()
	if err != nil {
		middleware.Logger.Info("redis set score failed eror",
			zap.Error(err),
		)
	}
}

//把企业微信数据塞入redis
func InsertwechatdataRedis(thisuserdetail model.UserDetail) {
	thisuserdetailMarshal, _ := json.Marshal(thisuserdetail)
	err := Cluster.Set(thisuserdetail.Mobile, thisuserdetailMarshal, 0).Err()
	if err != nil {
		middleware.Logger.Info("redis set score wechat data  failed eror",
			zap.Error(err),
		)
	}
	//将微信数据塞入到二叉树
	//Usertree.Insert(thisuserdetail)
}

//获取redis数据
func GetRedisValByKey(key, ShouldTable string) {
	//根据这个key删除这个redis的值
	defer Cluster.Del(key)
	val, err := Cluster.Get(key).Result()
	if err != nil {
		fmt.Printf("redis get  score failed, err:%v\n", err)
		return
	}
	var ThisEvent model.AlertEvent
	json.Unmarshal([]byte(val), &ThisEvent)
	fmt.Println("ThisEvent", ThisEvent, ThisEvent.EventDatasourceName, ThisEvent.EventDatasource)
	if !reflect.DeepEqual(ThisEvent, model.AlertEvent{}) {
		phones := make([]string, 0)
		Emails := make([]string, 0)
		contact_ids := make([]int, 0)
		wechat_contact_ids := make([]int, 0)
		email_contact_ids := make([]int, 0)
		var this_app_id int
		var way_ids string
		words := Substr(ThisEvent.AlertContent, 0, 50)
		//如果告警源是zabbix直接发给运维
		if ThisEvent.EventDatasource == "zabbix" {
			//判断运维的微信发送通道he 邮件发送通道 是否开启
			for _, way := range middleware.ThisAlertways {
				if strings.Contains(way.Name, "微信") && way.Yunwei_pause == false {
					userids := middleware.Yunweiuserid
					fmt.Println("运维userid", userids)
					way_ids = way_ids + "1,"
					//SendWechat(ThisEvent, userids)
				} else if strings.Contains(way.Name, "邮件") && way.Yunwei_pause == false {
					email_slice := make([]string, 0)
					email_slice = append(email_slice, "yunwei@china.zhaogang.com")
					way_ids = way_ids + "4,"
					//SendEmails(ThisEvent, email_slice)
				}
			}
		} else {
			phones, wechat_contact_ids, this_app_id = FindphonesByapplication(ThisEvent.SystemAlias, words, ThisEvent.EventOccurTimestamp, ShouldTable)
			fmt.Println("phones", phones)
			userIds := GetRedisUserDetailsBykey(phones)
			fmt.Println("userIds", userIds)
			//SendWechat(ThisEvent, userIds)
			//根据应用名称找到订阅邮箱的邮箱集合 (黑名单关键字)
			Emails, email_contact_ids = FindemailsByapplication(ThisEvent.SystemAlias, words, ThisEvent.EventOccurTimestamp, ShouldTable)
			fmt.Println("Emails", Emails)
			//SendEmails(ThisEvent, Emails)
		}
		//插入数据来源
		if ThisEvent.EventDatasource == "zabbix" {
			InsertSource("ZABBIX", ThisEvent.EventOccurTimestamp)
		} else if ThisEvent.EventDatasource == "app" {
			InsertSource("NSQ/KAFKA1", ThisEvent.EventOccurTimestamp)
		} else {
			InsertSource("KAFKA2", ThisEvent.EventOccurTimestamp)
		}
		//发送历史数据到ShouldTable  contact_id, app_id  eventOccurTimestamp words, way_ids, Should_table
		contact_ids = append(wechat_contact_ids, email_contact_ids...)
		contact_ids = RemoveRepeatedElement(contact_ids)

		if ThisEvent.EventDatasource != "zabbix" {
			for _, contact_id := range contact_ids {
				if isValueInList(contact_id, wechat_contact_ids) {
					way_ids = way_ids + "1,"
				}
				if isValueInList(contact_id, email_contact_ids) {
					way_ids = way_ids + "4,"
				}
				AlertHistoryAdd(contact_id, this_app_id, ThisEvent.EventOccurTimestamp, words, way_ids, ShouldTable)
				way_ids = ""
			}
		} else {
			AlertHistoryAdd(0, this_app_id, ThisEvent.EventOccurTimestamp, words, way_ids, ShouldTable)
			way_ids = ""
		}
	} else {
		fmt.Println("当前的redis还是空的")
	}
}

var ShouldTable string

//获取redis里面的待消费key值
func GetRedisKeys() {
	//发送历史数据表检测，没有就创建
	now := time.Now()
	year := now.Year()
	month := now.Month()
	my_day := fmt.Sprintf("%02d%02d\n", year, month)
	ShouldTable = "alertsendhistory" + my_day
	if !SearchTablehave("alertsendhistory" + my_day) {
		CreateTable(ShouldTable)
	}
	var cursor uint64
	keys, cursor, err := Cluster.Scan(cursor, middleware.RedisMasterKey+"*", 10000).Result()
	if err != nil {
		fmt.Println("scan keys failed err:", err)
		return
	}
	fmt.Println("ShouldTable", ShouldTable)
	fmt.Println("keys", keys)
	for _, key := range keys {
		go GetRedisValByKey(key, ShouldTable)
	}
}

func GetRedisUserIdsByname(name string) string {
	var cursor1 uint64
	keys, cursor1, err := Cluster.Scan(cursor1, "1*", 10000).Result()
	if err != nil {
		fmt.Println("scan keys failed err:", err)
		return ""
	}
	for _, key := range keys {
		val, _ := Cluster.Get(key).Result()
		var ThisUserdetail model.UserDetail
		json.Unmarshal([]byte(val), &ThisUserdetail)
		if ThisUserdetail.Name == name {
			return ThisUserdetail.UserID
		}
	}
	return ""
}

//根据phones获取redis里面model.UserDetail的集合
func GetRedisUserDetailsBykey(phones []string) (userids []string) {
	for _, phone := range phones {
		val, err := Cluster.Get(phone).Result()
		if err != nil {
			fmt.Printf("redis get  score failed, err:%v\n", err)
			return
		}
		var ThisUserDetail model.UserDetail
		json.Unmarshal([]byte(val), &ThisUserDetail)
		if !reflect.DeepEqual(ThisUserDetail, model.AlertEvent{}) {
			userids = append(userids, ThisUserDetail.UserID)
		}
	}
	return
}
